/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.drotposta.unitils;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Local;
import javax.ejb.Stateless;

/**
 *
 * @author elek
 */
public class EJBClassRegister {

    private Map<Class, Class> ejbsAndInterfaces = new HashMap();

    private static EJBClassRegister instance = new EJBClassRegister();

    /**
     * 0 - find interfaces
     * 1 - find implementations
     */
    private int mode;

    public static EJBClassRegister getInstance() {
        return instance;
    }

    public Class getImplementation(Class clazz) {
        return ejbsAndInterfaces.get(clazz);
    }

    public void load(File dir) {
        mode = 0;
        load(dir, dir);
        mode = 1;
        load(dir, dir);
    }

    public void load(File root, File dir) {
        if (dir.isDirectory()) {
            File files[] = dir.listFiles();
            for (File file : files) {
                if (file.isDirectory()) {
                    load(root, file);
                } else if (file.getName().endsWith(".class") && !file.getName().contains("$")) {
                    String prefix = root.getAbsolutePath();
                    String path = file.getAbsolutePath();
                    path = path.substring(prefix.length() + 1, path.length() - ".class".length());
                    path = path.replace("/", ".");
                    try {

                        Class ejbClass = Class.forName(path);
                        if (mode == 0 && ejbClass.isAnnotationPresent(Local.class)) {
                            ejbsAndInterfaces.put(ejbClass, ejbClass);
                        } else if (mode == 1 && ejbClass.isAnnotationPresent(Stateless.class)) {
                            Class ejbInterface = findInterface(ejbClass);
                            if (ejbInterface == null) {
                                throw new IllegalArgumentException("Not found interface for " + ejbClass.getCanonicalName());
                            }
                            ejbsAndInterfaces.put(ejbInterface, ejbClass);
                        }

                    } catch (ClassNotFoundException ex) {
                        Logger.getLogger(EJBClassRegister.class.getName()).log(Level.SEVERE, null, ex);
                    }

                }

            }
        }
    }

    private Class findInterface(Class ejbClass) {
        for (Class interfaze : ejbsAndInterfaces.keySet()) {
            if (interfaze.isAssignableFrom(ejbClass)) {
                return interfaze;
            }
        }
        return null;
    }
}
